﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="FormEffect.cs" company="Marcelo Roca">
//   Copyright (c) 2011 Marcelo Roca. All rights reserved.
// </copyright>
// <author name="Marcelo Roca" email="marce@marceloroca.com"/>
// <license>
//   This program is free software: you can redistribute it and/or modify
//   it under the terms of the GNU General Public License as published by
//   the Free Software Foundation, either version 3 of the License, or
//   (at your option) any later version.
// 
//   This program is distributed in the hope that it will be useful,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//   GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program.  If not, see http://www.gnu.org/licenses/.
// </license>
// --------------------------------------------------------------------------------------------------------------------

namespace GameKits.Unity.GuiForms.Forms
{
    using UnityEngine;

    public class FormEffect : FormCommand
    {
        /// <summary>
        /// El tipo de efecto
        /// </summary>
        protected readonly EffectTypes EffectType;

        /// <summary>
        /// El tipo de efecto
        /// </summary>
        protected readonly EffectPivots EffectPivot;

        /// <summary>
        /// Los segunds que durará el efecto
        /// </summary>
        private readonly float effectSeconds;

        /// <summary>
        /// El pivot del efecto
        /// </summary>
        private Vector2 pivot;

        /// <summary>
        /// La transparancie inicial del formulario
        /// </summary>
        private float formOpacity;

        /// <summary>
        /// El tiempo que ha transcurrido del efecto
        /// </summary>
        private float elapsedSeconds;

        /// <summary>
        /// El porcentaje que se ha ejecutado del efect
        /// </summary>
        private float executedPercent;

        /// <summary>
        /// Initializes a new instance of the <see cref="FormEffect"/> class.
        /// </summary>
        /// <param name="seconds">
        /// The seconds.
        /// </param>
        /// <param name="effectType">
        /// The effec type.
        /// </param>
        /// <param name="effectPivot">
        /// The effect privot.
        /// </param>
        public FormEffect(float seconds, EffectTypes effectType, EffectPivots effectPivot)
        {
            this.effectSeconds = seconds;
            this.EffectType = effectType;
            this.EffectPivot = effectPivot;
        }
     
        /// <summary>
        /// Inicializamos la instancia
        /// </summary>
        protected override void Initialize()
        {
            this.formOpacity = this.Parent.Opacity;

            switch (this.EffectPivot)
            {
                case EffectPivots.TopLeft:
                    this.pivot = new Vector2(this.Parent.WindowRect.x, this.Parent.WindowRect.y);
                    break;

                case EffectPivots.TopMiddle:
                    this.pivot = new Vector2(this.Parent.WindowRect.x + (this.Parent.WindowRect.width * 0.5f), this.Parent.WindowRect.y);
                    break;

                case EffectPivots.TopRight:
                    this.pivot = new Vector2(this.Parent.WindowRect.x + this.Parent.WindowRect.width, this.Parent.WindowRect.y);
                    break;

                case EffectPivots.MiddleLeft:
                    this.pivot = new Vector2(this.Parent.WindowRect.x, this.Parent.WindowRect.y + (this.Parent.WindowRect.height * 0.5f));
                    break;

                case EffectPivots.MiddleRight:
                    this.pivot = new Vector2(this.Parent.WindowRect.x + this.Parent.WindowRect.width, this.Parent.WindowRect.y + (this.Parent.WindowRect.height * 0.5f));
                    break;

                case EffectPivots.DownLeft:
                    this.pivot = new Vector2(this.Parent.WindowRect.x, this.Parent.WindowRect.y + this.Parent.WindowRect.height);
                    break;

                case EffectPivots.DownMiddle:
                    this.pivot = new Vector2(this.Parent.WindowRect.x + (this.Parent.WindowRect.width * 0.5f), this.Parent.WindowRect.y + this.Parent.WindowRect.height);
                    break;

                case EffectPivots.DownRight:
                    this.pivot = new Vector2(this.Parent.WindowRect.x + this.Parent.WindowRect.width, this.Parent.WindowRect.y + this.Parent.WindowRect.height);
                    break;

                default:
                    this.pivot = new Vector2(this.Parent.WindowRect.x + (this.Parent.WindowRect.width * 0.5f), this.Parent.WindowRect.y + (this.Parent.WindowRect.height * 0.5f));
                    break;
            }
        }

        /// <summary>
        /// Ejecuta el comando
        /// </summary>
        /// <returns>
        /// true si ha terminad de ejecvutar
        /// </returns>
        protected override bool DoExecute()
        {
            if (Event.current.type == EventType.Repaint)
            {
                this.elapsedSeconds += Time.deltaTime;
            }

            if (this.elapsedSeconds > this.effectSeconds)
            {
                this.elapsedSeconds = this.effectSeconds;
            }

            this.executedPercent = this.elapsedSeconds / this.effectSeconds;

            switch (this.EffectType)
            {
                case EffectTypes.Vibrate:
                    GUIUtility.RotateAroundPivot((Random.Range(-0.05f, .05f) * Mathf.Rad2Deg), this.pivot);
                    GUIUtility.ScaleAroundPivot(new Vector2(Random.Range(.95f, 1.05f), Random.Range(.95f, 1.05f)), this.pivot);
                    break;

                case EffectTypes.FadeIn:
                    Parent.Opacity = this.executedPercent * this.formOpacity;
                    break;

                case EffectTypes.FadeOut:
                    Parent.Opacity = (1 - this.executedPercent) * this.formOpacity;
                    break;

                case EffectTypes.ScaleIn:
                    GUIUtility.ScaleAroundPivot(new Vector2(this.executedPercent, this.executedPercent), this.pivot);
                    break;

                case EffectTypes.ScaleOut:
                    GUIUtility.ScaleAroundPivot(new Vector2(1 - this.executedPercent, 1 - this.executedPercent), this.pivot);
                    break;

                case EffectTypes.ScaleHeightIn:
                    GUIUtility.ScaleAroundPivot(new Vector2(1, this.executedPercent), this.pivot);
                    break;

                case EffectTypes.ScaleHeightOut:
                    GUIUtility.ScaleAroundPivot(new Vector2(1, 1 - this.executedPercent), this.pivot);
                    break;

                case EffectTypes.ScaleWidthIn:
                    GUIUtility.ScaleAroundPivot(new Vector2(this.executedPercent, 1), this.pivot);
                    break;

                case EffectTypes.ScaleWidthOut:
                    GUIUtility.ScaleAroundPivot(new Vector2(1 - this.executedPercent, 1), this.pivot);
                    break;
            }

            return this.executedPercent >= 1;
        }
    }
}
